#ifndef GAMEENGINE_H
#define GAMEENGINE_H

#include <map>
#include <SFML/System.hpp>

#include "util/Debug.hpp"
#include "util/Observable.hpp"
#include "util/FunctionTrigo.hpp"

#include "GameEngine/Map.hpp"
#include "GameEngine/Shot.hpp"
#include "GameEngine/Character.hpp"

using namespace std;

class GameEngine : public Observable, public sf::Thread
{
    public:
		enum    {NOTIFICATION_CODE_NEW_PLAYER       = 1,
			 	 NOTIFICATION_CODE_DELETE_PLAYER    = 2,
			 	 NOTIFICATION_CODE_SPAWN_PLAYER    	= 3,
				 NOTIFICATION_CODE_NEW_SHOT	       	= 4,
				 NOTIFICATION_CODE_DELETE_SHOT    	= 5,
				 NOTIFICATION_CODE_PLAYER_HIT    	= 6,
				 NOTIFICATION_CODE_PLAYER_KILL    	= 7,
				 NOTIFICATION_CODE_PLAYER_DIE    	= 8,
				 MAP_SIZE_X      					= 2048,
				 MAP_SIZE_Y    						= 2048};

        GameEngine(bool);
        virtual ~GameEngine();

        Character* GetPlayerById(unsigned int);
        Character* AddPlayer();
        Character* AddPlayer(
        		unsigned int p_id, 	string p_name, 		int p_status,
        		float p_positionX, 	float p_positionY, 	int p_directionV,
        		int p_directionH, 	unsigned int p_nbKill,
        		unsigned int p_nbDeath);
        void RemovePlayer(Character*);

        void Shoot(Character*, sf::Vector2f);
        void Shoot(Character*, float);

        void Stop();

        void GenerateMap();
        Map* GetMap()		{ return m_map; }

    protected:
    private:
        vector<Character*> 	m_listOfPlayers;
        vector<Shot*> 		m_listOfShot;
        Map* 				m_map;
        sf::Clock* 			m_Clock;
        unsigned int		m_counterIdPlayer;
        bool 				m_isRunning;
        bool				m_isServerSide;

        void SpawnPlayer();
        void RemoveAllPlayers();
        void RemoveAllShots();
        void RemoveOldShoot();

        virtual void Run();
};

#endif // GAMEENGINE_H
